home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
8bitfiles.net/archives
/
archives.tar
/
archives
/
compuserve-file-archive
/
09 Application Software
/
CONVER.DOC
< prev
next >
Wrap
Text File
|
2019-04-13
|
10KB
|
242 lines
MACHINE CODE PROGRAMMING EXAMPLE page 1
Have you ever looked at a doc file and discovered it was an ASCII file
instead of PETASCII. "NEW UTILITY" has a word-processor in it that
would convert it to a PETASCII, but some files are too long to fit, so
here is a program to convert them.
First, here is what the program had to do:
(1) Discard any linefeeds. This is a hex $0a or a decimal 10
code.
(2) Convert any values beginning at $41 (decimal 65) and ending
with $5a (decimal 90) to corresponding values in the range $c1 to
$da. This simply involved setting the high bit of the orginal
value. These values represent uppercase characters.
(3) Convert values in the $61 to $7a range to the corresponding
values in the $41 to $5a range. This is accomplished by
subtracting $20 from the orginal value.These values represent the
lower case letters.
To accomplish these objectives, the program combines a combination of
BASIC and machine language. BASIC is used to open the file and check
for disk errors and machine language to do the converting and write it
back to disk. The file is converted as it is read rather than have 2
files open to the disk (it can be done if you want) The converted file
is stored in a buffer beginning at $2000 (decimal 8192). When the
initial file has been converted, the program returns to BASIC to check
for disk errors, close the file, open the write file, check for a good
open, and then sys back to the machine language routine to write the
file to disk. A sequential file can never contain a hex $00, so that
is used to mark the end of the file in the buffer. When that marker is
reached, the program returns to BASIC to check for errors and close the
file. It's all straigt-forward and a beginner may be able to follow
the program well enough to get some understanding of machine language
programming.
Beginning at line 10, here is an explanation of the listing:
Line 10 thru 13 initializes a pointer located in zero page to the
address for the beginning of the buffer.
Line 14 and 15 set up file #8 as our input file.
Line 16 is the beginning of the main loop of this module. It gets
a byte from the disk drive.
Line 17 and 18 handle the line feeds contained in the ASCII file.
If these are left in the converted file then the printout will be
double spaced. A "CMP" op-code can give 3 possible results which
are:
(1) BCC - less-than (the carry is clear)
(2) BEQ - equal to (the zero flag is set)
(3) BCS - equal-to or greater-than (the carry-flag is set).
Lines 19 through 22 will trap all the codes in the $41 to $5a
range. In line 20, the branch will occur if the value is
LESS-THAN a $41. In line 22 the branch will occur if the value is
MACHINE CODE PROGRAMMING EXAMPLE page 2
GREATER-THAN a hex $5a. The comparison is actually made to a hex
$5b because the carry is set if the values are equal.
Line 23 sets the high bit of the orginal value and line 24 will
always branch because no value can be zero with the high bit set.
Line 25 through 28 traps the values in the range of $61 to $7a.
Lines 29 through 30 convert the values by subtracting a hex $20
from the orginal value. When the SBC opcode is used, it must be
preceded with the SEC opcode unless the status of the carry flag
is already known.
Lines 30 through 34 handle storing the converted value to the
buffer. The Y Register is set to zero in line 10 and it has not
been changed to this point. The value is actually stored at the
address pointed to at aux ($8b) PLUS the value of the Y register.
So the first time through the loop, aux contains the address $2000
in standard lo-byte - hi-byte format ($00 $20) and Y is 0, so the
first byte is stored at $2000. The second time around the loop,
the value is stored at $2001 because y is now 1. Y will be
incremented up to 255 ($FF) and at that point the value will be
stored at $20FF. When Y is incremented the new value will be 0
and this sets the zero flag tested by the BNE op-code, and since
it is "NOT EQUAL TO ZERO" then this branch will not occur and then
aux+1 is incremented. Aux will now contain a pointer to the
address $2100. This is how the converted values are stored in the
buffer and this process will continue as long as the main loop
continues.
Lines 35 to 38 check for the EOF and terminate the loop when it is
detected. The EOF is indicated by the sixth bit of the status
byte being set. When you AND the status byte with $40 (binary
0100 0000) the only two possible results are 0 and $40. Our
branch here occurs if the result is zero (in other words, the
sixth bit was NOT set).
Lines 38 and 39 put the eof marker in the buffer.
Line 40 restores the input and output devices to normal (input
keyboard - output screen).
Line 41 will return us to BASIC. The file has now been read from
the disk, converting it to PETASCII, and storing it to the
temporary buffer.
Line 42 is the beginning of the ML code for use when BASIC SYS's
back to write the converted file to disk. Line 42 through 45
initialize the zero page pointer to point to the address of $2000
(beginning of the temporary buffer).
Line 46 and 47 set up the disk file 8 as the output channel.
Line 48 initialized the Y Register to the value of zero.
Line 49 is the beginning of the main loop for the write module.
It gets a byte from the temporary buffer.
MACHINE CODE PROGRAMMING EXAMPLE page 3
Line 50 tests for the EOF marker and branches if detected.
Line 51 outputs the byte to the output channel (disk drive in this
case).
Lines 52 to 55 take care of managing the Y Register and the zero
page pointer. This works the same as in lines 32 through 34.
Line 56 restores the normal input and output channels and line 57
returns to BASIC. We only get here by detecting the EOF marker
back in line 50.
The finished code is located in the cassette buffer at decimal 828.
The object code is only 98 bytes long. The cassette buffer can hold up
to 192 bytes. This code is special in that it is "relocatable", ie.,
it can run at any address with out being modified.
Once the machine code was written and tested, then it was converted it
to data statements and added it to the BASIC program. This was done
with a program called "make data lines" and then the data file
generated was appended to the BASIC file with Tiny Aid. The completed
file was re-numbered with Tiny Aid to give it a finishing touch.
A side by side listing of the Machine Language portion follows. Hope
you enjoy this and let me know if you have any questions.
<<<<<...GAIL...>>>>>
LISTING FROM MERLIN ASSEMBLER
Program by Gail Cox
1 AUX = $8B
2 READST = $FFB7
3 CHKIN = $FFC6
4 CHKOUT = $FFC9
5 CLRCHN = $FFCC
6 CHROUT = $FFD2
7 GETIN = $FFE4
8 *
9 ORG 828
033C: A0 00 10 START LDY #$00
033E: 84 8B 11 STY AUX
0340: A9 20 12 LDA #$20
0342: 85 8C 13 STA AUX+1
0344: A2 08 14 LDX #$08
0346: 20 C6 FF 15 JSR CHKIN
0349: 20 E4 FF 16 MAIN JSR GETIN
034C: C9 0A 17 CMP #$0A ;no linefeed
034E: F0 F9 18 BEQ MAIN
0350: C9 41 19 CMP #'a' ;$41
0352: 90 13 20 BCC OK
MACHINE CODE PROGRAMMING EXAMPLE page 4
0354: C9 5B 21 CMP #'z'+1 ;$7b
0356: B0 04 22 BCS CKMOR
0358: 09 80 23 ORA #$80
035A: D0 0B 24 BNE OK
035C: C9 61 25 CKMOR CMP #'A' ;$61
035E: 90 07 26 BCC OK
0360: C9 7B 27 CMP #'Z'+1 ;$7b
0362: B0 03 28 BCS OK
0364: 38 29 SEC
0365: E9 20 30 SBC #$20
0367: 91 8B 31 OK STA (AUX),Y
0369: C8 32 INY
036A: D0 02 33 BNE CKST
036C: E6 8C 34 INC AUX+1
036E: 20 B7 FF 35 CKST JSR READST
0371: 29 40 36 AND #$40
0373: F0 D4 37 BEQ MAIN
0375: A9 00 38 LDA #$00
0377: 91 8B 39 STA (AUX),Y
0379: 20 CC FF 40 JSR CLRCHN
037C: 60 41 RTS
037D: A9 00 42 WRITE LDA #$00
037F: 85 8B 43 STA AUX
0381: A9 20 44 LDA #$20
0383: 85 8C 45 STA AUX+1
0385: A2 08 46 LDX #$08
0387: 20 C9 FF 47 JSR CHKOUT
038A: A0 00 48 LDY #$00
038C: B1 8B 49 WL LDA (AUX),Y
038E: F0 0A 50 BEQ FINISH
0390: 20 D2 FF 51 JSR CHROUT
0393: C8 52 INY
0394: D0 F6 53 BNE WL
0396: E6 8C 54 INC AUX+1
0398: D0 F2 55 BNE WL
039A: 20 CC FF 56 FINISH JSR CLRCHN
039D: 60 57 RTS
--End assembly, 98 bytes, Errors: 0